﻿using System;
using System.IO.Ports;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace BFCOMAssistant
{
    //定义一个委托
    public delegate void ReadComDataDelegate(byte[] ReadData, Int32 Len);
    public class ComPort
    {
        //定义一个串口对象
        private SerialPort comPort = new SerialPort();
        //定义一个事件
        public event ReadComDataDelegate ReadComDataEvent;
        //串口参数
        public ComPortConfig Parameter = new ComPortConfig();
        //定义一个数据接收的缓存
        private byte[] ReadComPortData = new byte[2048];

        //定义串口数据类型
        public class ComPortConfig
        {
            private string name;             //串口名称           
            private int baudRate;              //波特率          
            private int dataBit;               //数据位
            private int stopBit;               //停止位           
            private string parity;           //奇偶校验
            private string type;             //串口类型

            public string Type
            {
                get { return type; }
                set { type = value; }
            }

            public string Name
            {
                get { return name; }
                set { name = value; }
            }

            public int BaudRate
            {
                get { return baudRate; }
                set { baudRate = value; }
            }

            public int DataBit
            {
                get { return dataBit; }
                set { dataBit = value; }
            }

            public int StopBit
            {
                get { return stopBit; }
                set { stopBit = value; }
            }

            public string Parity
            {
                get { return parity; }
                set { parity = value; }
            }
        }

        public ComPort()
        {
            comPort.DataReceived += comPort_DataReceived; //注册一个串口接收事件
        }

        //初始化串口 
        private string Init(ComPortConfig ComPortParameter)
        {
            try
            {
                //Close();
                comPort.DtrEnable = true;
                comPort.RtsEnable = true;
                comPort.PortName = ComPortParameter.Name;
                comPort.BaudRate = ComPortParameter.BaudRate;

                switch (ComPortParameter.StopBit)
                {
                    case 1:
                        comPort.StopBits = StopBits.One;
                        break;
                    case 2:
                        comPort.StopBits = StopBits.None;
                        break;
                    case 3:
                        comPort.StopBits = StopBits.Two;
                        break;
                    default:
                        comPort.StopBits = StopBits.One;
                        break;
                }

                switch (ComPortParameter.Parity)
                {
                    case "None":
                        comPort.Parity = Parity.None;
                        break;
                    case "Odd":
                        comPort.Parity = Parity.Odd;
                        break;
                    case "Even":
                        comPort.Parity = Parity.Even;
                        break;
                    //case 4:
                    //    comPort.Parity = Parity.Mark;
                    //    break;
                    //case 5:
                    //    comPort.Parity = Parity.Space;
                    //break;
                    default:
                        comPort.Parity = Parity.None;
                        break;
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }

            return "OK";
        }

        //打开串口
        public string Open(ComPortConfig CommPortParameter)
        {
            string result = "";
            try
            {
                result = Init(CommPortParameter);

                if (comPort.IsOpen == false)
                {
                    comPort.Open();
                    Thread.Sleep(50);//如果串口打开成功，延时50ms再发送数据，保证串口运行稳定
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
            return result;
        }

        //关闭串口
        public string Close()
        {
            try
            {
                if (comPort.IsOpen == true)
                {
                    comPort.Close();
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
            return "OK";
        }

        //发送数据
        public string Write(string strData, string sendMode, out byte[] backData)
        {
            string result = "OK";
            backData = new byte[1];
            try
            {
                comPort.DiscardOutBuffer();
                if(sendMode == "HEX")
                {
                    result = BasicDataFormatLib.StringToHexByteArr(strData, out byte[] SendArray);
                    backData = new byte[SendArray.Length];
                    SendArray.CopyTo(backData, 0);
                    comPort.Write(SendArray, 0, SendArray.Length);
                }
                else //ASCII
                {
                    backData = new byte[strData.Length];
                    for (int i = 0; i < strData.Length; i++)
                    {
                        backData[i] = (byte)strData[i];
                    }
                    comPort.Write(strData);
                }
                
            }
            catch (Exception ex)
            {
                return ex.Message;
            }

            return result;
        }

        //串口接收事件
        private void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Int32 DataLen = comPort.BytesToRead;
            comPort.Read(ReadComPortData, 0, DataLen);
            ReadComDataEvent(ReadComPortData, DataLen);
        }

    }
}
